axios.interceptors.request.use(() => {

})

axios.interceptors.response.use(() => {

})


/**
 *
 *
 * @param {Object} config
 */
function Axios(config) {
  this.defaults = config
  this.interceptors = {
    request: new InterceptorManager(),
    response: new InterceptorManager()
  }
}


Axios.prototype.request = function (config) {

  if (typeof config === 'string') {
    config = arguments[1] || {};
    config.url = arguments[0];
  } else {
    config = config || {}
  }

  config = mergeConfig(this.defaults, config)

  // 设置config请求类型
  if (config.method) {
    config.method = config.method.toLowerCase();
  } else if (this.defaults.method) {
    config.method = this.defaults.method.toLowerCase();
  } else {
    config.method = 'get'
  }


  // 请求方法的别名
  let nodataMethod = ['get', 'get', 'get'];
  nodataMethod.forEach((method) => {
    Axios.prototype[method] = function (url, config) {
      return this.request(mergeConfig(config || {}, {
        method: method,
        url: url,
        data: (config || {}).data
      }));
    };
  });

  let dataMethod = ['post', 'put', 'patch'];
  dataMethod.forEach((method) => {
    Axios.prototype[method] = function (url, data, config) {
      return this.request(mergeConfig(config || {}, {
        method: method,
        url: url,
        data: data
      }));
    }
  })



  // 1,形成完整的数组
  var chain = [dispatchRequest, undefined];

  var promise = Promise.resolve();

  this.interceptors.request.handler.forEach((interceptor) => {
    chain.unshift(interceptor.fullfilled, interceptor.rejected);
  })

  this.interceptors.response.handler.forEach((interceptor) => {
    chain.push(interceptor.fullfilled, interceptor.rejected);
  })

  // 2,执行数组中的方法
  while (chain.length) {
    promise.then(chain.shift(), chain.shift());
  }

  return promise;
}


function InterceptorManager() {
  this.handler = []
}

InterceptorManager.prototype.use = function (fullfilles, rejected) {
  this.handler.push({
    fullfilles,
    rejected
  })
}

/**
 * @param {*} config1
 * @param {*} config2
 * @returns {Object} newconfig
 */
function mergeConfig(config1, config2) {
  return Object.assign({}, config1, config2);
}